﻿#pragma once

#include "AMain.h"
#include <string>
#include <vector>
#include <deque>
#include <any>
#include "../stringhelper.h"
#include "../tangible_filesystem.h"

namespace AutoPatcher
{
    class AMain : public System::Windows::Forms::Form
    {
    private:
        long long _totalBytes = 0, _completedBytes = 0, _currentBytes = 0;
        int _fileCount = 0, _currentCount = 0;

        FileInformation *_currentFile;
    public:
        bool Completed = false, Checked = false, ErrorFound = false;

        std::vector<FileInformation*> OldList;
        std::deque<FileInformation*> DownloadList;

    private:
        Stopwatch *_stopwatch = Stopwatch::StartNew();

        Thread *_workThread;

    public:
        virtual ~AMain()
        {
            delete _currentFile;
            delete _stopwatch;
            delete _workThread;
            delete components;
            delete pictureBox1;
            delete ImageLinkLabel;
            delete label1;
            delete ActionLabel;
            delete progressBar1;
            delete CancelButton;
            delete PlayButton;
            delete SizeLabel;
            delete label3;
            delete FileLabel;
            delete label5;
            delete SpeedLabel;
            delete label7;
            delete progressBar2;
            delete InterfaceTimer;
            delete SourceLinkLabel;
        }

        AMain();



        void Start();

    private:
        void BeginDownload();
        void CleanUp();
    public:
        bool NeedFile(const std::string &fileName);


        void ParseOld(BinaryReader *reader);

        void CheckFile(FileInformation *old);

        void Download(FileInformation *info);

        std::vector<unsigned char> Download(const std::string &fileName);

        static std::vector<unsigned char> Decompress(std::vector<unsigned char> &raw);
        static std::vector<unsigned char> Compress(std::vector<unsigned char> &raw);

        FileInformation *GetFileInformation(const std::string &fileName);

    private:
        void ImageLinkLabel_LinkClicked(std::any sender, LinkLabelLinkClickedEventArgs *e);

        void AMain_Load(std::any sender, EventArgs *e);

        void InterfaceTimer_Tick(std::any sender, EventArgs *e);

        void CancelButton_Click(std::any sender, EventArgs *e);

        void PlayButton_Click(std::any sender, EventArgs *e);

    public:
        void Play();

    private:
        void SourceLinkLabel_LinkClicked(std::any sender, LinkLabelLinkClickedEventArgs *e);




        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::IContainer *components = nullptr;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected:
        void Dispose(bool disposing) override;

        #pragma region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
    private:
        void InitializeComponent();

        #pragma endregion

        System::Windows::Forms::PictureBox *pictureBox1;
        System::Windows::Forms::LinkLabel *ImageLinkLabel;
        System::Windows::Forms::Label *label1;
        System::Windows::Forms::Label *ActionLabel;
        System::Windows::Forms::ProgressBar *progressBar1;
        System::Windows::Forms::Button *CancelButton;
        System::Windows::Forms::Button *PlayButton;
        System::Windows::Forms::Label *SizeLabel;
        System::Windows::Forms::Label *label3;
        System::Windows::Forms::Label *FileLabel;
        System::Windows::Forms::Label *label5;
        System::Windows::Forms::Label *SpeedLabel;
        System::Windows::Forms::Label *label7;
        System::Windows::Forms::ProgressBar *progressBar2;
        System::Windows::Forms::Timer *InterfaceTimer;
        System::Windows::Forms::LinkLabel *SourceLinkLabel;
    };
}
